﻿/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using antiufo.HttpPost;
using System.Collections.Specialized;
using System.Net;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of WeightClassStore.
	/// </summary>
	public class WeightClassStore : IStore<WeightClass>
	{
		private Site _site;
		public Site site {
			get { return _site; }
			set { _site = value; }
		}
		
		private HtmlWeb _client;
		
		private List<WeightClass> wclasses;

		private JsonDatabase db;

		public WeightClassStore(Site site, HtmlWeb client)
		{
			db = new JsonDatabase("sites/" + site.Name + "/WeightClasses");
			_site = site;
			_client = client;
			wclasses = new List<WeightClass>();
		}

		public WeightClass GetItem(string WeightClassId)
		{
			string url = _site.Url + "/admin/json.php?action=load_weight_classes&module=weight_classes&weight_class_id=" + WeightClassId;

			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");

			try {
				JObject json = (JObject)JsonConvert.DeserializeObject(node.InnerText);
				foreach (JProperty property in json.Properties()) {
					if (property.Name == "data") {
						var val = property.Value.ToString();
						WeightClass wclass = new WeightClass(val);
						wclass.Store = this;
						return wclass;
					}
				}

				throw new Exception("Could not load the WeightClass " + WeightClassId);
			} catch (JsonReaderException ex) {
//				return null;
				throw ex;
			}
		}

		public void PersistItems(List<WeightClass> items)
		{
			db.Write<List<WeightClass>>(items, _site.Name);
		}

		public void Truncate()
		{
//			foreach(WeightClass wclass in wclasses)
//			{
//				if(!wclass.is_default)
//				{
//					DeleteItem(wclass);
//				}
//			}
			db.Truncate();
		}

		public void PersistItem(WeightClass item)
		{
			db.Write<WeightClass>(item,item.weight_class_key);
		}

		public bool MoveItem(string itemId, string folderId)
		{
			throw new NotImplementedException();
		}

		public bool DeleteItem(string itemId)
		{
			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=delete_weight_class&module=weight_classes&weight_classes_id=" + itemId);

			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "success") {
					var response = bool.Parse(json[key].ToString());
					if (response) {
						db.Delete<WeightClass>(itemId);
					}

					return response;
				}
			}

			return false;
		}

		public WeightClass[] LoadItems()
		{
			WeightClass[] items = db.Read<WeightClass>();
			foreach(WeightClass item in items)
			{
				item.Store = this;
			}
			return items;
		}

		public WeightClass LoadItem(string itemId)
		{
			WeightClass item = db.Read<WeightClass>(itemId);
			if (item != null) {
				item.Store = this;
				return item;
			}

			return null;
		}

		public bool Contains(WeightClass item)
		{
			throw new NotImplementedException();
		}

		public List<WeightClass> GetItems()
		{
			db.Truncate();
			
			wclasses = new List<WeightClass>();

			HtmlDocument doc = _client.Load(_site.Url + "/admin/json.php?action=list_weight_classes&module=weight_classes");
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");

			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string, object> json = serialiser.Deserialize<Dictionary<string, object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						WeightClass weightClass = GetItem(record["weight_class_id"].ToString());
						wclasses.Add(weightClass);
						PersistItem(weightClass);
					}
				}
			}
			
			PersistItems(wclasses);
			
			return wclasses;
		}
		
		public string Default_language_id {
			get
			{
				var languages = site.GetLanguageStore().LoadItems();
				
				foreach(Language language in languages)
				{
					if(language.is_default)
					{
						return language.languages_id;
					}
				}
				
				throw new Exception("Could not get the default language ID in store " + site.Name);
			}
		}

		public bool UpdateItem(WeightClass item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("action", "save_weight_classes");
			post.AddField("module", "weight_classes");
			post.AddField("weight_class_id",item.weight_class_id);
			
			if(item.is_default)
			{
				post.AddField("is_default", "on");
			}
			
			foreach(string key in item.keys.Keys)
			{
				post.AddField(key,item.keys[key]);
			}

			foreach(string key in item.names.Keys)
			{
				post.AddField(key,item.names[key]);
			}

			foreach(WeightClassRule rule in item.rules)
			{
				post.AddField("rules[" + rule.weight_class_id + "]",rule.weight_class_rule);
			}
			
			var resp = post.PostData(PostMethod.UrlEncoded);

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();

			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						return bool.Parse(json[key].ToString());
					}
				}
			}

			throw new Exception("Could not update the WeightClass " + item.weight_class_title + " in site " + _site.Name);
		}

		public string InsertItem(WeightClass item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("action", "save_weight_classes");
			post.AddField("module", "weight_classes");
			if(item.is_default)
			{
				post.AddField("is_default", "on");
			}
			
			foreach(string key in item.keys.Keys)
			{
				post.AddField(key,item.keys[key]);
			}

			foreach(string key in item.names.Keys)
			{
				post.AddField(key,item.names[key]);
			}

			foreach(WeightClassRule rule in item.rules)
			{
				post.AddField("rules[" + rule.weight_class_id + "]",rule.weight_class_rule);
			}

			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();

			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						if (bool.Parse(json[key].ToString())) {
							
							var wclasses = GetItems();
							
							foreach(WeightClass wclass in wclasses)
							{
								if(wclass.weight_class_key == item.weight_class_key)
								{
									return wclass.weight_class_id;
								}
							}
						}
					}
				}
			}

			throw new Exception("Could not insert the WeightClass " + item.weight_class_title + " in site " + _site.Name);
		}
	}
}
